/*
 * Created on Jan 1, 2005
 */
package org.scohen.juploadr.upload;

import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.scohen.juploadr.Messages;
import org.scohen.juploadr.app.ImageAttributesEXIFCreateDateComparator;
import org.scohen.juploadr.app.ImageAttributesRankComparator;
import org.scohen.juploadr.app.JUploadr;
import org.scohen.juploadr.app.RescaleTask;
import org.scohen.juploadr.app.UploadImage;
import org.scohen.juploadr.event.UploadStatusMonitor;
import org.scohen.juploadr.prefs.Configuration;
import org.scohen.juploadr.prefs.ConfigurationDialog;
import org.scohen.juploadr.ui.MessageUtils;
import org.scohen.juploadr.ui.ProgressDialog;
import org.scohen.juploadr.ui.ReusableUIFactory;
import org.scohen.juploadr.uploadapi.ImageUploadApi;

/**
 * @author steve
 */
public class UploadManager extends SelectionAdapter {
    private Map<String,? extends UploadImage> attributes;
    private LinkedList<UploadImage> uploadQueue;
    private UploadStatusMonitor monitor;
    private UploaderThread uploaderThread;
    private Configuration config;

    public UploadManager(Map<String, ? extends UploadImage> attributes) {
        this.attributes = attributes;

        this.uploadQueue = new LinkedList<UploadImage>();
        config = Configuration.getInstance();
        uploaderThread = new UploaderThread(this.uploadQueue, monitor);
        this.startUploaderThread();
    }

    public UploadManager(Map<String,? extends UploadImage> attributes, UploadStatusMonitor monitor) {
        this(attributes);
        this.monitor = monitor;
        uploaderThread.setMonitor(monitor);
    }

    /**
     * 
     */
    private void startUploaderThread() {
        uploaderThread.setDaemon(true);
        uploaderThread.start();
    }

    public void widgetSelected(SelectionEvent event) {
        // check to see if they've entered anything in the config
        ImageUploadApi api = ImageUploadApi.getInstance();
        if (!api.isCurrentAccountAuthenticated()) {
            MessageUtils.showErrorMessage(Messages.getString("juploadr.ui.error.please.authorize")); //$NON-NLS-1$
            ConfigurationDialog dialog = new ConfigurationDialog(ReusableUIFactory.getInstance().getDisplay()
                    .getShells()[0]);
            dialog.open();
        }

        if (api.isCurrentAccountAuthenticated()) {
            // time to send the images.
                    
            List<UploadImage> list = new LinkedList<UploadImage>(attributes.values());
            removeUploadedPhotos(list);
            Comparator<UploadImage> sorter = null;
            if (config.getUploadByExifDate()) {
                sorter = new ImageAttributesEXIFCreateDateComparator();
            } else {
                sorter = new ImageAttributesRankComparator();
            }
            Collections.sort(list, sorter);

            if (config.isProxyEnabled() && !config.proxySettingsValid()) {
                MessageUtils.showErrorMessage(Messages.getString("juploadr.ui.error.proxy.settings.incorrect")); //$NON-NLS-1$
                return;
            }

            Button button = (Button) event.widget;
            if (!uploaderThread.isCancelled()
                    && Messages.getString("juploadr.ui.button.upload.text.stop").equals(button.getText())) {
                uploaderThread.setCancelled(true);
                button.setEnabled(false);
                button.setText(Messages.getString("juploadr.ui.button.upload.text.upload"));
            } else {
                button.setText(Messages.getString("juploadr.ui.button.upload.text.stop"));
                uploaderThread.setCancelled(false);

                synchronized (UploadManager.this.uploadQueue) {
                    if (config.getAutoResizePhotos()) {
                        RescaleTask rescale = new RescaleTask(list);
                        ProgressDialog pd = new ProgressDialog(JUploadr.window, rescale);
                        pd.execute();
                        list = rescale.getRescaledPhotos();
                    }

                    Iterator values = list.iterator();
                    while (values.hasNext()) {
                        UploadImage attrs = (UploadImage) values.next();
                        if (!uploadQueue.contains(attrs)) {

                            // adding to position zero effectively reverses the
                            // order.
                            // they're uploaded back to front, so it comes out
                            // correctly
                            // in your photostream.
                            this.uploadQueue.add(0, attrs);
                            this.uploadQueue.notify();
                        }
                    }
                }
            }
        }
    }

    private void removeUploadedPhotos(Collection photos) {
        Iterator iter = photos.iterator();
        while (iter.hasNext()) {
            UploadImage image = (UploadImage) iter.next();
            if (image.getState() == UploadImage.STATE_REMOVED || image.getState() == UploadImage.STATE_UPLOADED) {
                iter.remove();
            }
        }
    }
}